#pragma once
#include <bitset>
#include <queue>
#include <boost/array.hpp>
#include "InputAtom.h"
#include "Point.h"
#include "ImportExport.h"

namespace ja2{ namespace sgp
{
	//! Input manager.
	class InputManager : boost::noncopyable
	{
		// Typedefs
	private:
		//! Make sure to refer to the translation table which is within one of the following files (depending on the language used). ENGLISH.C, JAPANESE.C, FRENCH.C, GERMAN.C, SPANISH.C, etc...
		typedef boost::array<std::uint16_t, 1024> KeyTranslationTable_t;
		//! Table is used to track which of the keys is up or down at any one time. This is used while polling the interface.
		typedef std::bitset<256> KeyState_t;
		//! Event queue.
		typedef std::queue<InputAtom> EventQueue_t;

		// Attributes
	private:
		//! Instance used by hook methods.
		static InputManager *m_pInstance;
		//! Current window.
		HWND m_Window;
		//! Next mouse hook.
		HHOOK m_MouseHook;
		//! Key translation table.
		KeyTranslationTable_t m_KeyTranslationTable;
		//! Input was received.
		bool m_InputReceived;
		//! Event queue.
		EventQueue_t m_EventQueue;
		//! Track mouse movement.
		bool m_TrackMousePos;
		//! Left button state.
		/*!
			true = Pressed, false = Not Pressed.

			--REFERENCE--: gfLeftButtonState
		*/
		bool m_LeftButtonState;
		//! Right button state.
		/*!
			--REFERENCE--: gfRightButtonState
		*/
		bool m_RightButtonState;

		// Operations
	public:
		//! Get current mouse position.
		Point JA2_SGP_API cursor_position() const;
		//! Left button down.
		JA2_SGP_API bool left_button_down() const;
		//! Right button down.
		JA2_SGP_API bool right_button_down() const;
	private:
		//! Queue new event.
		void queue_event(InputAtom::EventType InputEvent, std::int_least16_t MouseX, std::int_least16_t MouseY, bool IsShiftDown, bool IsCtrlDown, bool IsAltDown, std::uint_least16_t WheelDelta);
		//! Mouse hook proc.
		static LRESULT CALLBACK mouse_handler(int Code, WPARAM wParam, LPARAM lParam);

		// Constructor/Destructor
	public:
		JA2_SGP_API InputManager(HWND Window);
	};
} /*sgp*/} /*ja2*/
